package com.aizuda.boot.modules.business.contractNumber;

import com.aizuda.boot.modules.business.contract.entity.ContractEntity;
import com.aizuda.boot.modules.business.contract.entity.ContractFieldValueEntity;
import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowEntity;
import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowTypeEntity;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldValueMapper;
import com.aizuda.boot.modules.business.contract.mapper.ContractMapper;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowService;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowTypeService;
import com.aizuda.boot.modules.business.contractNumber.domain.resquest.GenerateNumberDTO;
import com.aizuda.boot.modules.common.constant.enums.RuleTypeEnums;
import com.aizuda.boot.modules.business.contractNumber.service.ContractNumberRuleService;
import com.aizuda.boot.modules.flw.entity.FlwProcessForm;
import com.aizuda.boot.modules.flw.service.IFlwProcessFormService;
import com.aizuda.bpm.engine.TaskTrigger;
import com.aizuda.bpm.engine.core.Execution;
import com.aizuda.bpm.engine.entity.FlwInstance;
import com.aizuda.bpm.engine.model.NodeModel;
import com.aizuda.service.spring.SpringHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author sangyirong
 * @ClassName NumberTaskTrigger
 * @Version 1.0
 * @Date 2025/7/15 10:22
 */
@Slf4j
@Component
public class NumberTaskTrigger implements TaskTrigger {

    @Override
    public boolean execute(NodeModel nodeModel, Execution execution, Function<Execution, Boolean> finish) {
        CompletableFuture.runAsync(() -> asyncExec(execution, finish));
        return true;
    }

    private void asyncExec(Execution execution, Function<Execution, Boolean> finish) {
        try {
            execution.setSaveAsDraft(true);
            log.info("开始执行触发器任务 {}", execution.getFlwTask().getId());

            // 通过SpringHelper获取Spring管理的Bean
            ContractMapper contractMapper = SpringHelper.getBean(ContractMapper.class);
            ContractNumberRuleService contractNumberRuleService = SpringHelper.getBean(ContractNumberRuleService.class);
            ContractFieldValueMapper contractFieldValueMapper = SpringHelper.getBean(ContractFieldValueMapper.class);
            ContractWorkflowTypeService contractWorkflowTypeService = SpringHelper.getBean(ContractWorkflowTypeService.class);
            ContractWorkflowService contractWorkflowService = SpringHelper.getBean(ContractWorkflowService.class);
            IFlwProcessFormService flwProcessFormService = SpringHelper.getBean(IFlwProcessFormService.class);

            FlwInstance flwInstance = execution.getFlwInstance();
            if (null == flwInstance){
                log.error("流程实例不存在");
            }

            FlwProcessForm flwProcessForm = flwProcessFormService.getByInstanceId(flwInstance.getId());
            if (null == flwProcessForm){
                log.error("流程表单不存在");
            }
            String content = flwProcessForm.getContent();
            JSONObject jsonObject = JSON.parseObject(content);
            Integer contractId = (Integer) jsonObject.get("contractId");

            ContractEntity contractEntity = contractMapper.selectById(contractId);

            if (null != contractEntity) {
                //8 —> 收支类型     19 —> 我方     25 —> 合同类型
                GenerateNumberDTO dto = new GenerateNumberDTO();
                Map<Long, String> fieldMap = contractFieldValueMapper.selectList(Wrappers.<ContractFieldValueEntity>lambdaQuery()
                                .eq(ContractFieldValueEntity::getContractId, contractId)
                                .in(ContractFieldValueEntity::getFieldId, 8, 18, 25))
                        .stream().collect(Collectors.toMap(ContractFieldValueEntity::getFieldId, ContractFieldValueEntity::getFieldValue));
                dto.setContractTypeId(Integer.parseInt(fieldMap.get(25L)));
                dto.setDocumentType(getDocument(fieldMap.get(8L)));
                String own = fieldMap.get(19L);
                List<Integer> ownIds = JSON.parseArray(own, Integer.class);
                dto.setLegalId(ownIds.get(0));
                int typeId = Integer.parseInt(fieldMap.get(25L));

                List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(
                        new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                                .eq(ContractWorkflowTypeEntity::getContractTypeId, typeId)
                );

                List<Long> workflowIds = workflowTypes.stream()
                        .map(ContractWorkflowTypeEntity::getWorkflowId)
                        .collect(Collectors.toList());


                List<ContractWorkflowEntity> workflows = contractWorkflowService.list(
                        new LambdaQueryWrapper<ContractWorkflowEntity>()
                                .in(ContractWorkflowEntity::getId, workflowIds)
                                .eq(ContractWorkflowEntity::getIsEnabled, true)
                                .orderByDesc(ContractWorkflowEntity::getPriority)
                );

                ContractWorkflowEntity selectedWorkflow = workflows.get(0);

                dto.setRuleType(getRuleType(selectedWorkflow.getWorkflowType()));

                String contractNumber = contractNumberRuleService.getContractNumber(dto);
                contractFieldValueMapper.update(Wrappers.<ContractFieldValueEntity>lambdaUpdate()
                        .set(ContractFieldValueEntity::getFieldValue, contractNumber)
                        .eq(ContractFieldValueEntity::getContractId, contractId)
                        .eq(ContractFieldValueEntity::getFieldId, 23L));
                log.info("生成合同编号成功，合同编号：{}", contractNumber);
            }

            log.info("任务执行完成");
            execution.setSaveAsDraft(false);
            finish.apply(execution);
        } catch (Exception e) {
            log.error("任务执行失败\n", e);
            execution.setSaveAsDraft(false);
            finish.apply(execution);
        }
    }

    private RuleTypeEnums getRuleType(String workflowType) {
       return RuleTypeEnums.valueOf( switch (workflowType){
           case "CHANGE" -> "CONTRACT_CHANGE";
           case "TERMINATION" -> "CONTRACT_TERMINATE";
           case "OTHER" -> "CONTRACT_GROUP";
           default -> "CONTRACT_APPLY";
       });
    }


    public String getDocument(String type) {
        return switch (type) {
            case "支出类" -> "EXP";
            case "收入类" -> "INC";
            case "无收无支类" -> "BAL";
            case "既收又支类" -> "MIX";
            default -> "OTH";
        };
    }
}
